class Response {
    statusCode: number;
    statusMessage: string;
    headers: { [key: string]: string };
    body?: any;

    constructor(
        statusCode: number,
        statusMessage: string,
        headers?: { [key: string]: string },
        body?: any
    ) {
        this.statusCode = statusCode;
        this.statusMessage = statusMessage;
        this.headers = headers || {};
        this.body = body;
    }
}

class RestResponse extends Response {
    constructor(
        statusCode: number,
        statusMessage: string,
        headers?: { [key: string]: string },
        body?: object
    ) {
        super(statusCode, statusMessage, headers, body);

        if (body) {
            this.headers["Content-Type"] = "application/json";
        }
    }
}

class Response200 extends RestResponse {
    constructor(body?: object, headers?: { [key: string]: string }) {
        super(200, "OK", headers, body);
    }
}

class Response201 extends RestResponse {
    constructor(body?: object, headers?: { [key: string]: string }) {
        super(201, "Created", headers, body);
    }
}

class Response400 extends RestResponse {
    constructor(body?: object, headers?: { [key: string]: string }) {
        super(400, "Bad Request", headers, body);
    }
}

class Response404 extends RestResponse {
    constructor(body?: object, headers?: { [key: string]: string }) {
        super(404, "Not Found", headers, body);
    }
}

class Response405 extends RestResponse {
    constructor(body?: object, headers?: { [key: string]: string }) {
        super(405, "Method Not Allowed", headers, body);
    }
}

class Response409 extends RestResponse {
    constructor(body?: object, headers?: { [key: string]: string }) {
        super(409, "Conflict", headers, body);
    }
}

class Response500 extends RestResponse {
    constructor(body?: object, headers?: { [key: string]: string }) {
        super(500, "Internal Server Error", headers, body);
    }
}

class Html {
    content: string;
    constructor(content: string) {
        this.content = content;
    }

    toString(): string {
        return this.content;
    }
}

export {
    Response,
    RestResponse,
    Response200,
    Response201,
    Response400,
    Response404,
    Response405,
    Response409,
    Response500,
    Html,
};
